﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Dmo_lc_2.Shape;
using Newtonsoft.Json;
using System.Diagnostics;

namespace Dmo_lc_2
{
    public class Class1
    {
        public static double LTSSCALE = 1; // 线型比例因子 针对线型 虚线等

        [CommandMethod("mytest")]
        public void CADTest()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            //Editor ed = doc.Editor;

            var proPath = "";   //文件目录
            var proName = "";   //文件名
            var inputPath = ""; //输入目录
            var outputPath = ""; //输出目录
            int i = 0;
            foreach (string arg in Environment.GetCommandLineArgs())
            {
                if (i == 5)
                {
                    proPath = arg;
                }
                if (i == 6)
                {
                    proName = arg;
                }
                //ed.WriteMessage("\n Arg{0}=\"{1}\"", i++, arg);
                //MessageBox.Show(arg);
                i++;
            }

            inputPath = proPath.Substring(0, proPath.Length - 7) + "input\\" + proName + ".dwg";

            outputPath = proPath.Substring(0, proPath.Length - 7) + "input\\" + proName + ".json";


            using (Database db = new Database(false, true))
            {
                try
                {
                    // 读取dwg文件
                    db.ReadDwgFile(inputPath,FileOpenMode.OpenForReadAndAllShare, false, "");
                    db.CloseInput(true);
                }
                catch (System.Exception ex)
                {
                    doc.Editor.WriteMessage("\nUnable to read drawing file.");
                    return;
                }

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    string userSerialize = genSceneData(db ,tr);
                    System.IO.File.WriteAllText(outputPath, userSerialize);
                    //System.Environment.Exit(0);
                    Process.GetCurrentProcess().Kill();
                }
            }

            //string text = "A class is the most powerful data type in C#. Like a structure, " + "a class defines the data and behavior of the data type. ";
            //System.IO.File.WriteAllText(@"WriteText.txt", text);
            //MessageBox.Show("Hello 我们!");
        }

        [CommandMethod("localtest")]
        public void CADLocalTest()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            using (Database db = HostApplicationServices.WorkingDatabase)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    string userSerialize = genSceneData(db,tr);
                    //System.IO.File.WriteAllText(@"D:\Work_Space\Git\CadEngineDemo\demo\model\data.json", userSerialize);
                    System.IO.File.WriteAllText(@"C:\dev\CadEngineDemo\demo\model\data.json", userSerialize);
                }
            }

            string text = "A class is the most powerful data type in C#. Like a structure, " + "a class defines the data and behavior of the data type. ";
        }

        private string genSceneData(Database db , Transaction tr) {
            string re = "";

            LTSSCALE = db.Ltscale;
            // 模型空间
            BlockTable blkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead)
                as BlockTable;
            BlockTableRecord modelSpace = tr.GetObject(
                blkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead)
                as BlockTableRecord;
            List<BaseShape> listShape = new List<BaseShape>();

            double[] sceneBound = new double[] { -10000000.0, -10000000.0, 10000000.0, 10000000.0 };
            // 遍历模型空间
            foreach (ObjectId oid in modelSpace)
            {
                DBObject dbobj = tr.GetObject(oid, OpenMode.ForRead);

                if (dbobj is Entity)
                {
                    Entity entity = dbobj as Entity;
                    LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
                    LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(entity.LayerId, OpenMode.ForRead);

                    BaseShape bs = ShapeFactory.genShapeByEntity(tr, dbobj);
                    if (bs != null && bs.shapeType != BaseShape.ShapeType.BASE && entity.Visible) {
                        try
                        {
                            if (((Extents3d)dbobj.Bounds).MaxPoint.X > sceneBound[0]) sceneBound[0] = ((Extents3d)dbobj.Bounds).MaxPoint.X;
                            if (((Extents3d)dbobj.Bounds).MaxPoint.Y > sceneBound[1]) sceneBound[1] = ((Extents3d)dbobj.Bounds).MaxPoint.Y;
                            if (((Extents3d)dbobj.Bounds).MinPoint.X < sceneBound[2]) sceneBound[2] = ((Extents3d)dbobj.Bounds).MinPoint.X;
                            if (((Extents3d)dbobj.Bounds).MinPoint.Y < sceneBound[3]) sceneBound[3] = ((Extents3d)dbobj.Bounds).MinPoint.Y;
                        }
                        catch (System.Exception ex)
                        {
//                            sceneBound[0] = 0;
//                            sceneBound[1] = 0;
//                            sceneBound[2] = 0;
//                            sceneBound[3] = 0;
                        }
                        listShape.Add(bs);
                    }

                    //string entityStr = JsonConvert.SerializeObject(bs);
                    //Console.WriteLine(entityStr);

                    //LinetypeTableRecord lineType = new LinetypeTableRecord();
                    //lineType.d

                }
            }

            string userSerialize = JsonConvert.SerializeObject(listShape);
            re = "{\"content\":" + userSerialize + ",";
            re += "\"bound\":" + JsonConvert.SerializeObject(sceneBound) + "}";

            return re;
        }


        //private void defaultLayerFix()
        //{

        //    // Open a transaction for fixing layers that have the correct name
        //    // but not the correct color or linetype.
        //    using (curTrans = db.TransactionManager.StartOpenCloseTransaction())
        //    {

        //        // Open the layerTable and lineType table for read.
        //        dwgLyrTbl = curTrans.GetObject(
        //            db.LayerTableId, OpenMode.ForRead) as LayerTable;
        //        acLinTbl = curTrans.GetObject(
        //            db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;

        //        // Check each layer against the standard layers DataSet.
        //        foreach (ObjectId layID in dwgLyrTbl)
        //        {
        //            LayerTableRecord curLayer = curTrans.GetObject(
        //                layID, OpenMode.ForRead) as LayerTableRecord;

        //            var layerFound = _LayerDataTable.Rows.Find(curLayer.Name.ToUpper());
        //            if (layerFound != null)
        //            {

        //                // Upgrade the layerTable and LayerRecord for write.
        //                dwgLyrTbl.UpgradeOpen();
        //                curLayer.UpgradeOpen();


        //                // modify the color of the layer
        //                curLayer.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(
        //                    Autodesk.AutoCAD.Colors.ColorMethod.ByAci, (short)layerFound[2]);

        //                // I tried to put it in its own transaction in hopes that it would help.. but it didnt
        //                using (Transaction tempTrans = db.TransactionManager.StartOpenCloseTransaction())
        //                {

        //                    // if the layer is not loaded in the current dwg
        //                    if (!acLinTbl.Has((string)layerFound[3]))
        //                        try
        //                        {
        //                            db.LoadLineTypeFile((string)layerFound[3], "acad.lin");
        //                        }
        //                        catch (Autodesk.AutoCAD.Runtime.Exception e)
        //                        {
        //                            Editor ed = acDoc.Editor;
        //                            ed.WriteMessage(e.Message);
        //                        }

        //                    tempTrans.Commit();
        //                }

        //                // Change current layer linetype to...
        //                curLayer.LinetypeObjectId = acLinTbl[(string)layerFound[3]];

        //                // Downgrade the layerTable, lineTable and the LayerRecord for read.
        //                curLayer.DowngradeOpen();
        //                dwgLyrTbl.DowngradeOpen();

        //                // Remove the layer from the standards list
        //                // so we do not attempt to have redundant layers.
        //                for (int i = _LayerDataTable.Rows.Count - 1; i >= 0; i--)
        //                {
        //                    System.Data.DataRow dr = _LayerDataTable.Rows[i];
        //                    if (dr["NAME"] == layerFound[0])
        //                    {
        //                        dr.Delete();
        //                        break;
        //                    }
        //                }
        //            }
        //            else
        //            {

        //                // if the layer is not in within standard add it to a data set
        //                // to fix manually.
        //                if (curLayer.Name == "0")
        //                    continue;
        //                var newRow = LayersToFix.NewRow();
        //                newRow["NAME"] = curLayer.Name;
        //                // TODO get color name..
        //                newRow["COLOR"] = curLayer.Color.ColorName;
        //                newRow["COLOR_ID"] = 0;
        //                LinetypeTableRecord Ltype = (LinetypeTableRecord)curTrans.GetObject(
        //                    curLayer.LinetypeObjectId, OpenMode.ForRead
        //                );
        //                newRow["LINETYPE"] = Ltype.Name;
        //                LayersToFix.Rows.Add(newRow);
        //            }
        //        }
        //        // accept the changes made in this transaction
        //        curTrans.Commit();
        //    }
        //}
    }
}
